<!--
 * @Author: adolphus adolphus520@163.com
 * @Date: 2022-12-10 00:33:42
 * @LastEditors: 姚杰鸿
 * @LastEditTime: 2024-11-11 15:51:58
 * @Description: file content
-->
<template>
  <div>
    <transition name="aside-tran" mode="out-in">
      <div class="menu-search">
        <el-input
          v-if="showTitle"
          class="menu-search-input"
          v-model="menuSearch"
          placeholder="检索功能"
          @keyup.enter="searchMenu"
        >
          <template #prepend>
            <el-button icon="Search" @click="searchMenu" />
          </template>
        </el-input>
        <el-button v-else class="menu-search-input" icon="Search" />
      </div>
    </transition>
    <el-scrollbar class="menu-scroll">
      <ul class="el-menu el-menu--vertical el-menu-vertical-demo">
        <MdsMenuItem
          v-for="(item, index) in items"
          :key="index"
          :model="item"
          :show-title="showTitle"
          @extend="extend"
          @menu-click="menuClick"
        />
      </ul>
    </el-scrollbar>
  </div>
</template>

<script lang="ts" setup>
import { PropType, ref, onMounted, watch } from "vue";
import { v4 as uuidv4 } from "uuid";
import { useRoute, useRouter } from "vue-router";
import * as vars from "@/lib/vars";

const menuProps = defineProps({
    menuItems: {
      type: Array as PropType<vars.menuItem[]>,
      default: () => [],
    },
    saveExtend: {
      type: Boolean,
      default: true,
    },
    oneExtend: {
      type: Boolean,
      default: false,
    },
    showTitle: {
      type: Boolean,
      default: true,
    },
    actpath: {
      type: String,
      default: "",
    },
  }),
  menuSearch = ref(null),
  items = ref<vars.menuItem[]>(),
  $route = ref(useRoute()),
  $router = ref(useRouter()),
  modules = import.meta.glob("@/views/**/**.vue"),
  extend = (id: string) => {
    _extend(items.value, id);
    _extend(menuProps.menuItems, id);
  },
  _college = (items: any) => {
    for (let i in items) {
      let item = items[i];
      item.isExtend = false;
    }
  },
  _extend = (items: any, id: string) => {
    for (let i in items) {
      let item = items[i];
      if (item.id == id) {
        item.isExtend = !item.isExtend;
        if (!menuProps.saveExtend) {
          _college(item.items);
        }
        if (menuProps.oneExtend && item.isExtend) {
          for (let j in items) {
            let _item = items[j];
            if (_item.id != id && _item.isExtend) {
              _item.isExtend = false;
            }
          }
        }
      } else if (item.items) {
        _extend(item.items, id);
      }
    }
  },
  _active = (items: any, path: string) => {
    let hv = false;
    for (let i in items) {
      let item = items[i];
      if (null != item.router && item.router.path == path) {
        item.active = true;
        hv = true;
      } else if (item.items) {
        item.active = _active(item.items, path);
        if (item.active) hv = true;
      } else {
        item.active = false;
      }
    }
    return hv;
  },
  getMenuItemById = (items: any, id: string) => {
    for (let i in items) {
      let item = items[i];
      if (item.id == id) {
        return item;
      } else if (item.items) {
        item = getMenuItemById(item.items, id);
        if (item) return item;
      }
    }
    return null;
  },
  setMenuItemId = (items: any) => {
    for (let i in items) {
      let item = items[i];
      item.id = uuidv4();
      if (item.items) {
        setMenuItemId(item.items);
      }
    }
  },
  addMenuItemRoute = (items: any) => {
    for (let i in items) {
      let item = items[i];
      if (null != item.router && null != item.router.component) {
        console.log(item.router.component);
        $router.value.addRoute({
          path: item.router.path,
          name: item.name,
          component: modules[`/views/${item.router?.component}`],
        });
      }
      if (item.items) {
        addMenuItemRoute(item.items);
      }
    }
  },
  menuClick = (id: string) => {
    let item = getMenuItemById(items.value, id);
    if (null != item.router && null != item.router.component) {
      $router.value.push(item.router);
    }
  },
  searchMenu = () => {
    items.value = _searchMenu(
      JSON.parse(JSON.stringify(menuProps.menuItems)),
      menuSearch.value
    );
  },
  _searchMenu = (items: any, search: string | null) => {
    if (!search) return items;
    let _items = Array<vars.menuItem[]>();
    for (let i in items) {
      let item = items[i];
      if (-1 < item.name.indexOf(search)) {
        _items.push(item);
      } else if (item.items) {
        let res = _searchMenu(item.items, search);
        if (0 < res.length) {
          item.items = res;
          _items.push(item);
        }
      }
    }
    return _items;
  };

onMounted(() => {
  setMenuItemId(menuProps.menuItems);
  addMenuItemRoute(menuProps.menuItems);
  items.value = JSON.parse(JSON.stringify(menuProps.menuItems));
});

watch(
  () => menuProps.actpath,
  (newValue, oldValue) => {
    _active(menuProps.menuItems, menuProps.actpath);
    items.value = _searchMenu(
      JSON.parse(JSON.stringify(menuProps.menuItems)),
      menuSearch.value
    );
  }
);
watch(
  () => menuProps.menuItems,
  (newValue) => {
    items.value = newValue;
    setMenuItemId(items.value);
    addMenuItemRoute(items.value);
  }
);
</script>

<style lang="scss" scoped>
// 折叠加隐藏过渡效果
.aside-tran-enter-active,
.aside-tran-leave-active {
  transition: all 0.15s ease;
  overflow: hidden;
}

.aside-tran-enter-from,
.aside-tran-leave-to {
  max-width: 60px !important;
}
.aside-tran-enter-to,
.aside-tran-leave-from {
  max-width: 250px !important;
}

.menu-scroll {
  height: calc(100vh - 140px);
}

.menu-search {
  padding-right: 7px;
  border-right: 1px solid var(--el-menu-border-color);
}

.menu-search-input {
  height: 40px;
  font-size: 15px;
}
</style>
